package com.bigknow.appstore.web.base.service.impl;

import com.bigknow.appstore.common.AppStoreRuntimeException;
import com.bigknow.appstore.web.base.dao.ICommentDao;
import com.bigknow.appstore.web.base.dao.IUserDao;
import com.bigknow.appstore.web.base.entity.User;
import com.bigknow.appstore.web.base.service.ICommentService;
import com.bigknow.appstore.web.base.service.IUserService;
import com.bigknow.appstore.web.base.vo.FancyTreeVo;
import com.bigknow.appstore.web.console.app.Application;
import com.bigknow.appstore.web.console.app.Comment;
import com.bigknow.appstore.web.framework.security.SecInfo;
import com.bigknow.appstore.web.framework.service.BaseCRUDService;
import com.bigknow.appstore.web.framework.util.GlobalConstant;
import com.bigknow.appstore.web.framework.util.SecUtils;
import com.bigknow.fusion.common.inf.server.appstore.FusionHandler;
import com.bigknow.fusion.web.base.entity.enums.State;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.tools.ant.util.DateUtils;
import org.mongodb.morphia.Datastore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * Created by zhangwei on 2016/11/01.
 */
@Service
public class CommentService extends BaseCRUDService<Comment, ICommentDao> implements ICommentService {
    @Autowired
    private Datastore ds;

    @Override
    public void insertComment(String appId, float score, String content, boolean anonymous) {
        com.bigknow.appstore.web.base.entity.User user = (com.bigknow.appstore.web.base.entity.User) SecurityUtils.getSubject().getPrincipal();
        Comment comment = new Comment();
        comment.setId(UUID.randomUUID().toString());
        comment.setAnonymous(anonymous);
        comment.setUserId(user.getId());
        comment.setUpdateTime(DateUtils.format(new Date(), com.bigknow.appstore.auth.infrastructure.DateUtils.DEFAULT_DATE_TIME_FORMAT));
        comment.setScore(score);
        comment.setContent(content);
        comment.setAppId(appId);
        comment.setForStat(false);
        ds.save(comment);
        updateStar(comment);
    }

    private void updateStar(Comment comment) {
        Comment stat = ds.find(Comment.class).filter("appId", comment.getAppId()).filter("forStat", true).get();
        long commentNum = 1l;
        float totalScore = comment.getScore();
        if (stat == null) {
            Comment _stat = new Comment();
            _stat.setId(UUID.randomUUID().toString());
            _stat.setAppId(comment.getAppId());
            _stat.setUpdateTime(DateUtils.format(new Date(), com.bigknow.appstore.auth.infrastructure.DateUtils.DEFAULT_DATE_TIME_FORMAT));
            _stat.setCommentNum(commentNum);
            _stat.setTotalScore(totalScore);
            _stat.setForStat(true);
            ds.save(_stat);
        } else {
            totalScore = totalScore + stat.getTotalScore();
            commentNum = commentNum + stat.getCommentNum();
            ds.update(stat, ds.createUpdateOperations(Comment.class).set("totalScore", totalScore).set("commentNum", commentNum));
        }
        Application app = ds.find(Application.class).filter("id", comment.getAppId()).get();
        ds.update(app, ds.createUpdateOperations(Application.class).set("star", calcAverage(commentNum, totalScore)));
    }

    private float calcAverage(Long commentNum, float totalScore) {
        float remainder = totalScore / commentNum;
        int round = Math.round(remainder);
        float subResult = round - remainder;
        if (subResult > 0) {
            if (subResult > 0.25) {
                return (float) Math.floor(remainder) + 0.5f;
            } else {
                return round;
            }
        } else {
            if (subResult > -0.25) {
                return (float) Math.floor(remainder);
            } else {
                return (float) Math.floor(remainder) + 0.5f;
            }
        }
    }
}
